package LinkedList.doubleLinkedList;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class DoubleLinkedList {
    private HeroNode head;
    private HeroNode tail;
    private int size;
    @Data
    static
    class HeroNode{
        private int no;
        private String name;
        private HeroNode pre;
        private HeroNode next;
        public HeroNode() {
            pre = null;
            next = null;
        }
        public HeroNode(int no, String name) {
            this.no = no;
            this.name = name;
            pre = null;
            next = null;
        }
        @Override
        public String toString() {
            return "HeroNode{" +
                    "no=" + no +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    public HeroNode getFirst(){
        return this.head;
    }
    public HeroNode getLast(){
        return this.tail;
    }
    public void display(){
        System.out.println("========================");
        HeroNode tmp = this.head;
        while(tmp!=null){
            System.out.println(tmp);
            tmp = tmp.next;
        }
        System.out.println("over=================");
    }
    public void addLast(HeroNode node) {
        if (isEmpty()){
            head = node;
        }
        if (isNotEmpty()){
            tail.next = node;
            node.pre = tail;
        }
        tail = node;
        size++;
    }
    public void addByOrder(HeroNode node){
        HeroNode preHead = new HeroNode();
        preHead.next = this.head;
        HeroNode tmp = preHead;
        while(true){
            if (tmp.next==null){
                addLast(node);
                break;
            }
            if (tmp.next.getNo()> node.getNo()){
                if(tmp.next==head){
                    preHead.next=node;
                    node.next=head;
                    head.pre=node;
                    head = node;
                    size++;
                }else {
                    node.next=tmp.next;
                    tmp.next.pre=node;
                    tmp.next=node;
                    node.pre=tmp;
                    size++;
                }
                break;
            }
            tmp = tmp.next;
        }
    }
    public boolean isEmpty(){
        return size==0;
    }
    public boolean isNotEmpty(){
        return !isEmpty();
    }
    public void remove(int index){
        HeroNode rmvNode = getAt(index);
        if (rmvNode.pre == null){
            this.head = rmvNode.next;

            rmvNode.next.pre = null;
            rmvNode.next = null;
            return ;
        }
        if (rmvNode.next == null){
            this.tail=rmvNode.pre;
            rmvNode.pre.next = null;
            rmvNode.pre = null;
            return ;
        }
        rmvNode.pre.next = rmvNode.next;
        rmvNode.next.pre = rmvNode.pre;
        rmvNode = null;
    }

    /**
     * 很骚的方法是把size右移2位，相当于处以2 在与index比较看是从前遍历还是后面
     * @param index
     */
    public HeroNode getAt(int index){
        HeroNode tmp = this.head;
        for (int i = 1; i <=index-1; i++) {
            tmp = tmp.next;
        }
        return tmp;
    }

}
